package com.com.gmail.at.vssabinin.adminclient;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import DTO.ScheduleDTO;
import DTO.StationDTO;
import DTO.TrainDTO;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JButton;
import javax.swing.ListSelectionModel;

public class ScheduleManager extends javax.swing.JDialog {

	private static final long serialVersionUID = 1L;

    public ScheduleManager(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        setResizable(false);
        initComponents();
    }
    
    private HashSet<ScheduleDTO> createdSchedules = new HashSet<ScheduleDTO>();
    private HashSet<ScheduleDTO> removedSchedules = new HashSet<ScheduleDTO>();
    
    private DefaultTableModel tableModel = new DefaultTableModel(null, new String [] 
    		{"Train number", "Departure station", "Arrival station", "Departure date", "Arrival date"});
    private DefaultComboBoxModel departureTrainsComboBox = new DefaultComboBoxModel();
    private DefaultComboBoxModel arrivalTrainsComboBox = new DefaultComboBoxModel();
    private DefaultComboBoxModel trainNumbersComboBox = new DefaultComboBoxModel();
    
    private boolean changes = false;

    private SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
    
    public static ScheduleManager scheduleInstance = new ScheduleManager(Main.mainInstance, true);
    
    public void update() {
    	this.changes = false;
    	this.createdSchedules.clear();
    	this.removedSchedules.clear();
    	if (this.tableModel.getRowCount() > 0) {
    	    for (int i = this.tableModel.getRowCount() -1; i > -1; i--) {
    	    	this.tableModel.removeRow(i);
    	    }
    	}
    	this.trainNumbersComboBox.removeAllElements();
    	this.departureTrainsComboBox.removeAllElements();
    	this.arrivalTrainsComboBox.removeAllElements();
    	Main.mainInstance.client.sendThroughProtocol("adminManageScheduleDat", "");
        Protocol.Message message1 = Main.mainInstance.client.readThroughProtocol();
        if (message1.getType().equals("ok")) {
        	@SuppressWarnings("unchecked")
        	List<ScheduleDTO> schedules = (List<ScheduleDTO>)message1.getObject();
            for (int i = 0; i < schedules.size(); i++) {
            	String[] row = {schedules.get(i).getTrainNumber().toString(), schedules.get(i).getStation1(), schedules.get(i).getStation2(),
            			dataFormat.format(schedules.get(i).getDateOfDeparture()), dataFormat.format(schedules.get(i).getDateOfArrival())};
            	this.tableModel.addRow(row);
            }
        } else if (message1.getType().equals("no")) {
        	
        }
        Main.mainInstance.client.sendThroughProtocol("adminManageStatDat", "");
        Protocol.Message message2 = Main.mainInstance.client.readThroughProtocol();
        if (message2.getType().equals("ok")) {
        	@SuppressWarnings("unchecked")
        	List<StationDTO> station = (List<StationDTO>)message2.getObject();
            for (int i = 0; i < station.size(); i++) {
            	this.arrivalTrainsComboBox.addElement(station.get(i).getStationName());
            	this.departureTrainsComboBox.addElement(station.get(i).getStationName());
            }
        } else if (message2.getType().equals("no")) {
        	this.arrivalTrainsComboBox.addElement("No stations in DB");
        	this.departureTrainsComboBox.addElement("No stations in DB");
        }
        Main.mainInstance.client.sendThroughProtocol("adminManageTrainDat", "");
        Protocol.Message message3 = Main.mainInstance.client.readThroughProtocol();
        if (message3.getType().equals("ok")) {
        	@SuppressWarnings("unchecked")
        	List<TrainDTO> train = (List<TrainDTO>)message3.getObject();
            for (int i = 0; i < train.size(); i++) {
            	this.trainNumbersComboBox.addElement(train.get(i).getTrainNumber());
            }
        } else if (message3.getType().equals("no")) {
        	trainNumbersComboBox.addElement("No trains in DB");
        }
        this.trainNumber.setModel(trainNumbersComboBox);
        this.scheduleTable.setModel(tableModel);
        this.departureStation.setModel(departureTrainsComboBox);
        this.arrivalStation.setModel(arrivalTrainsComboBox);
    }

    private void initComponents() {

        departureStation = new javax.swing.JComboBox();
        arrivalStation = new javax.swing.JComboBox();
        departureDate = new javax.swing.JTextField();
        arrivalDate = new javax.swing.JTextField();
        create = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        trainNumber = new javax.swing.JComboBox();
        jLabel5 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        scheduleTable = new javax.swing.JTable();
        scheduleTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        delete = new javax.swing.JButton();
        save = new javax.swing.JButton();
        goBack = new javax.swing.JButton();
        refresh = new javax.swing.JButton();
        

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
       

        departureStation.setMaximumSize(new java.awt.Dimension(56, 20));

        arrivalStation.setMaximumSize(new java.awt.Dimension(56, 20));

        departureDate.setText("2012.11.19 19:11:11");

        arrivalDate.setText("2012.11.20 20:11:11");

        create.setText("create");
        
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });
        
        create.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                createMouseReleased(evt);
            }
        });

        jLabel1.setText("Departure station");

        jLabel2.setText("Arrival station");

        jLabel3.setText("Departure date");

        jLabel4.setText("Arrival date");

        trainNumber.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        trainNumber.setMaximumSize(new java.awt.Dimension(56, 20));
      
        jLabel5.setText("Train number");

       
        scheduleTable.setMaximumSize(new java.awt.Dimension(375, 64));
        scheduleTable.setMinimumSize(new java.awt.Dimension(375, 64));
        jScrollPane1.setViewportView(scheduleTable);

        delete.setText("delete selected row");
        
        delete.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                deleteMouseReleased(evt);
            }
        });

        save.setText("save changes");
        save.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                saveMouseReleased(evt);
            }
        });

        goBack.setText("go back to the main menu");
        goBack.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                goBackMouseReleased(evt);
            }
        });

        refresh.setText("refresh table");
        refresh.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                refreshMouseReleased(evt);
            }
        });
        
        JButton checkPassengersOn = new JButton("check passengers on selected schedule");
        
        checkPassengersOn.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
            	checkPassengersOn(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        layout.setHorizontalGroup(
        	layout.createParallelGroup(Alignment.TRAILING)
        		.addGroup(layout.createSequentialGroup()
        			.addContainerGap()
        			.addGroup(layout.createParallelGroup(Alignment.TRAILING)
        				.addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 875, Short.MAX_VALUE)
        				.addGroup(layout.createSequentialGroup()
        					.addGroup(layout.createParallelGroup(Alignment.LEADING)
        						.addComponent(jLabel5, GroupLayout.PREFERRED_SIZE, 69, GroupLayout.PREFERRED_SIZE)
        						.addComponent(trainNumber, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE))
        					.addPreferredGap(ComponentPlacement.RELATED, 78, Short.MAX_VALUE)
        					.addGroup(layout.createParallelGroup(Alignment.LEADING)
        						.addComponent(departureStation, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE)
        						.addComponent(jLabel1))
        					.addGap(73)
        					.addGroup(layout.createParallelGroup(Alignment.LEADING)
        						.addComponent(arrivalStation, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE)
        						.addComponent(jLabel2))
        					.addGap(56)
        					.addGroup(layout.createParallelGroup(Alignment.LEADING)
        						.addComponent(departureDate, Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
        						.addComponent(jLabel3, Alignment.TRAILING, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE))
        					.addGap(28)
        					.addGroup(layout.createParallelGroup(Alignment.LEADING)
        						.addGroup(layout.createSequentialGroup()
        							.addComponent(arrivalDate, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
        							.addGap(32)
        							.addComponent(create))
        						.addComponent(jLabel4)))
        				.addGroup(layout.createSequentialGroup()
        					.addComponent(goBack)
        					.addGap(36)
        					.addComponent(checkPassengersOn)
        					.addGap(48)
        					.addComponent(delete, GroupLayout.PREFERRED_SIZE, 137, GroupLayout.PREFERRED_SIZE)
        					.addPreferredGap(ComponentPlacement.RELATED, 53, Short.MAX_VALUE)
        					.addComponent(refresh)
        					.addGap(31)
        					.addComponent(save)))
        			.addContainerGap())
        );
        layout.setVerticalGroup(
        	layout.createParallelGroup(Alignment.LEADING)
        		.addGroup(layout.createSequentialGroup()
        			.addGap(13)
        			.addGroup(layout.createParallelGroup(Alignment.BASELINE)
        				.addComponent(jLabel3)
        				.addComponent(jLabel4)
        				.addComponent(jLabel5)
        				.addComponent(jLabel2)
        				.addComponent(jLabel1))
        			.addPreferredGap(ComponentPlacement.RELATED)
        			.addGroup(layout.createParallelGroup(Alignment.BASELINE)
        				.addComponent(departureDate, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
        				.addComponent(arrivalDate, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
        				.addComponent(create)
        				.addComponent(trainNumber, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
        				.addComponent(arrivalStation, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
        				.addComponent(departureStation, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
        			.addGap(18)
        			.addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 329, Short.MAX_VALUE)
        			.addGap(18)
        			.addGroup(layout.createParallelGroup(Alignment.BASELINE)
        				.addComponent(goBack)
        				.addComponent(refresh)
        				.addComponent(save)
        				.addComponent(checkPassengersOn)
        				.addComponent(delete))
        			.addContainerGap())
        );
        getContentPane().setLayout(layout);

        pack();
    }

   
    private void goBackMouseReleased(java.awt.event.MouseEvent evt) {
    	if (changes) {
    		int selection = JOptionPane.showConfirmDialog(null, "Do you want to save changes?", "Information", 
        			JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE);
        	if (selection == JOptionPane.YES_OPTION) {
        		this.saveMouseReleased(evt);
        	}
    	}
    	Main.mainInstance.loginViewSet();
        this.dispose();
    }

    private void createMouseReleased(java.awt.event.MouseEvent evt) {
    	Date dateOfArrival = null;
    	Date dateOfDeparture = null;
    	boolean badInput = false;
		try {
			dateOfArrival = dataFormat.parse(this.arrivalDate.getText());
			dateOfDeparture = dataFormat.parse(this.departureDate.getText());
		} catch (ParseException e) {
			badInput = true;
			JOptionPane.showMessageDialog(null, "Incorrect date format!"); 
		} 
		if (!badInput) {
			if (dateOfArrival.compareTo(dateOfDeparture) > 0) {
				ScheduleDTO schedule = new ScheduleDTO();
		        schedule.setDateOfArrival(dateOfArrival);
		        schedule.setDateOfDeparture(dateOfDeparture);
		        try {
		        	schedule.setTrainNumber(Integer.valueOf(this.trainNumber.getSelectedItem().toString()));
		        } catch (NumberFormatException e) {
		        	JOptionPane.showMessageDialog(null, "Train number is not correct, check it!");
		        	return;
		        }
		        if (((String)this.departureStation.getSelectedItem()).equals("No stations in DB")) {
		        	JOptionPane.showMessageDialog(null, "Stations names are not correct, check them!");
		        	return;
		        }
		        schedule.setStation1((String)this.departureStation.getSelectedItem());
		        schedule.setStation2((String)this.arrivalStation.getSelectedItem()); 
		    	this.createdSchedules.add(schedule);
		    	String[] row = {schedule.getTrainNumber().toString(), schedule.getStation1(), schedule.getStation2(), 
		    			dataFormat.format(schedule.getDateOfArrival()), dataFormat.format(schedule.getDateOfDeparture())};
		    	this.tableModel.addRow(row);
		    	ScheduleManager.scheduleInstance.scheduleTable.setModel(tableModel);
		    	this.changes = true;
			} else {
				JOptionPane.showMessageDialog(null, "Date of arrival should be later than the date of departure!");
			}
		}
		this.changes = true;
    }

    private void saveMouseReleased(java.awt.event.MouseEvent evt) {
    	if (!this.createdSchedules.isEmpty()) {
        	Main.mainInstance.client.sendThroughProtocol("adminCreateSchedules", this.createdSchedules);
        	Protocol.Message message = Main.mainInstance.client.readThroughProtocol();
        	if (message.getType().equals("ok")) {
        		this.createdSchedules.clear();	
        	}
        }
        if (!this.removedSchedules.isEmpty()) {
        	Main.mainInstance.client.sendThroughProtocol("adminRemoveSchedules", this.removedSchedules);
        	Protocol.Message message1 = Main.mainInstance.client.readThroughProtocol();
        	if (message1.getType().equals("ok")) {
        		this.removedSchedules.clear();	
        	}
		}
        this.update();
        JOptionPane.showMessageDialog(null, "You have successfully made ​​changes!"); 
    }
    
    private void checkPassengersOn(java.awt.event.MouseEvent evt) {
    	int id = this.scheduleTable.getSelectedRow();
    	if(changes) {
    		int selection = JOptionPane.showConfirmDialog(null, "Sorry but befor you should save changes," +
    				" would you like to do it,?", 
    				"Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
        	if (selection == JOptionPane.YES_OPTION) {
        		this.saveMouseReleased(evt);
        	} else {
        		return;
        	}
    	}
    	ScheduleDTO schedule = new ScheduleDTO();
    	if (id != -1) { 
    		Date dateOfArrival = null;
        	Date dateOfDeparture = null;
    		try {
    			dateOfArrival = dataFormat.parse((String) this.tableModel.getValueAt(id, 4));
    			dateOfDeparture = dataFormat.parse((String)this.tableModel.getValueAt(id, 3));
    		} catch (ParseException e) {
    			JOptionPane.showMessageDialog(null, "Internal error, try once more!");
    			this.update();
    		}
            schedule.setDateOfArrival(dateOfArrival);
            schedule.setDateOfDeparture(dateOfDeparture);
    		schedule.setTrainNumber(Integer.valueOf((String)this.tableModel.getValueAt(id, 0)));
        	schedule.setStation1((String)this.tableModel.getValueAt(id, 1));
        	schedule.setStation2((String)this.tableModel.getValueAt(id, 2));
        	PassengersOnTrainReview.passOnTrainInstance.scheduleDTO = schedule;
        	PassengersOnTrainReview.passOnTrainInstance.update();
        	this.dispose();
        	PassengersOnTrainReview.passOnTrainInstance.setLocationRelativeTo(null);
        	PassengersOnTrainReview.passOnTrainInstance.setVisible(true);
        	
    	} else {
    		JOptionPane.showMessageDialog(null, "Illegal selection!"); 
    	}
    }
    
    private void refreshMouseReleased(java.awt.event.MouseEvent evt) {
    	this.update();
    }
    
    private void formWindowOpened(java.awt.event.WindowEvent evt) {
        this.update();
    }

    private void deleteMouseReleased(java.awt.event.MouseEvent evt) {
    	ScheduleDTO schedule = new ScheduleDTO();
    	int id = this.scheduleTable.getSelectedRow();
    	if (id != -1) { 
    		int selection = JOptionPane.showConfirmDialog(null, "This will delete the schedule, and " +
    				"all the tickets, that are associated with it!", "Warning", JOptionPane.YES_NO_OPTION, 
    				JOptionPane.WARNING_MESSAGE);
        	if (selection == JOptionPane.YES_OPTION) {
        		Date dateOfArrival = null;
            	Date dateOfDeparture = null;
        		try {
        			dateOfArrival = dataFormat.parse((String) this.tableModel.getValueAt(id, 4));
        			dateOfDeparture = dataFormat.parse((String)this.tableModel.getValueAt(id, 3));
        		} catch (ParseException e) {
        			JOptionPane.showMessageDialog(null, "Internal error, try once more!");
        			this.update();
        		}
                schedule.setDateOfArrival(dateOfArrival);
                schedule.setDateOfDeparture(dateOfDeparture);
        		schedule.setTrainNumber(Integer.valueOf((String)this.tableModel.getValueAt(id, 0)));
            	schedule.setStation1((String)this.tableModel.getValueAt(id, 1));
            	schedule.setStation2((String)this.tableModel.getValueAt(id, 2));
            	this.tableModel.removeRow(id);
            	this.removedSchedules.add(schedule);
            	ScheduleManager.scheduleInstance.scheduleTable.setModel(tableModel);
        	}
    	}
    }
    
    public static void main(String args[]) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ScheduleManager.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ScheduleManager.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ScheduleManager.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ScheduleManager.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
    
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                ScheduleManager dialog = new ScheduleManager(new javax.swing.JFrame(), true);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                    @Override
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }
    private javax.swing.JTextField arrivalDate;
    private javax.swing.JComboBox arrivalStation;
    private javax.swing.JButton create;
    private javax.swing.JButton delete;
    private javax.swing.JTextField departureDate;
    private javax.swing.JComboBox departureStation;
    private javax.swing.JButton goBack;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable scheduleTable;
    private javax.swing.JButton refresh;
	private javax.swing.JButton save;
	private javax.swing.JComboBox trainNumber;

}
